
const getRawBody = require("raw-body")
const {parseXML} = require("../extend/weChatHelp")
const xml2js = require("xml2js")
const WXBizMsgCrypt = require("wechat-crypto")
module.exports = options => {
	/**
	 * @type {import("egg"). CbMiddle}
	 */
	let messageHandle = async function (ctx, next) {
		if (ctx.header["content-type"] != "text/xml") {
			ctx.status = 404
			ctx.body = ""
		}
		let str = (await getRawBody(ctx.req)).toString()
		ctx.weixinXml = str
		let wechatObj = await parseXML(str)
		ctx.wechatObj = wechatObj && wechatObj.xml
		if (!ctx.wechatObj) {
			ctx.status = 400
			ctx.body = ""
			return
		}
		let wxBizMsgCrypt
		if (typeof wechatObj.Encrypt == "string") {
			wxBizMsgCrypt = new WXBizMsgCrypt(ctx.wechat.token, ctx.wechat.encoding_aeskey, ctx.wechat.app_id)
			let parseStat = false
			let {timestamp, nonce} = ctx.query
			if (ctx.query.msg_signature === wxBizMsgCrypt.getSignature(timestamp, nonce, wechatObj.Encrypt)) {
				var decryptedXML = wxBizMsgCrypt.decrypt(wechatObj.Encrypt)
				var messageWrapXml = decryptedXML.message
				if (messageWrapXml !== "") {
					var decodedXML = await parseXML(messageWrapXml)
					ctx.wechatObj = decodedXML && decodedXML.xml
					if (ctx.wechatObj) {
						parseStat = false
					}
				}
			}
			if (!parseStat) {
				ctx.body = ""
				ctx.status = 400
				return
			}
		}
		ctx.wechatUser = await ctx.service.wechatUser.fetchUserInfo(ctx.wechatObj.FromUserName)
		await next()
		let builder = new xml2js.Builder()  // JSON->xml
		if (!ctx.xmlBody) {
			throw new Error("未知响应内容 程序错误")
		}
		ctx.xmlBody.ToUserName = ctx.xmlBody.toUsername || ctx.wechatObj.FromUserName
		ctx.xmlBody.FromUserName = ctx.xmlBody.FromUserName || ctx.wechatObj.ToUserName
		ctx.xmlBody.Content = ctx.xmlBody.Content || ""
		ctx.xmlBody.CreateTime = (Date.now() / 1000 | 0).toString()


		ctx.body = builder.buildObject({xml: ctx.xmlBody})
		if (typeof wechatObj.Encrypt == "string") {
			var wrap = {}
			wrap.encrypt = wxBizMsgCrypt.encrypt(ctx.body)
			wrap.nonce = parseInt((Math.random() * 100000000000), 10)
			wrap.timestamp = new Date().getTime()
			wrap.signature = wxBizMsgCrypt.getSignature(wrap.timestamp, wrap.nonce, wrap.encrypt)
			ctx.body = builder.buildObject(wrap)
		}
	}
	return messageHandle
}